package com.ats.impl.tws;

import com.ib.client.Contract
import com.ib.client.ContractDetails
import com.ib.client.EWrapper
import com.ib.client.Execution
import com.ib.client.Order
import com.ib.client.OrderState;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory
import com.ats.api.util.Util
import com.ats.api.model.{TickerIdMapper, HistoricalTickData}
;

/**
 *  Receive messages from TWS
 *
 *  reroute message to adapter
 *
 * @param ewadapter
 */

class EWrapperImpl(ewadapter: EWrapperAdapter) extends EWrapper {

  private final val logger = LoggerFactory.getLogger(getClass());

  def bondContractDetails(arg0: Int, arg1: ContractDetails) {

  }

  def contractDetails(arg0: Int, arg1: ContractDetails) {

  }

  def contractDetailsEnd(arg0: Int) {

  }

  def currentTime(currentTime: Long) {
    logger.debug("System.currentTime" + currentTime);
  }

  def execDetails(id: Int, contract: Contract, execution: Execution) {
    logger.debug("id" + id + ":contarct" + Util.toXML(contract) + "Execution" + Util.toXML(execution));
  }

  def fundamentalData(id: Int, data: String) {
    logger.debug("" + id + "data" + Util.toXML(data));
  }

  def historicalData(reqId: Int, date: String, open: Double, high: Double, low: Double, close: Double, volume: Int, count: Int, wap: Double, hasgaps: Boolean) {
    val contract: Contract = TickerIdMapper.getContract(reqId);
    val tickSymbol = contract.m_symbol
    val tickData = new HistoricalTickData(tickSymbol, wap, "", date);
    tickData.requestId = reqId;
    tickData.open = open
    tickData.high = high;
    tickData.low = low;
    tickData.close = close;
    tickData.volume = volume;
    tickData.count = count;
    tickData.wap = wap;
    tickData.hasgaps = hasgaps;
    logger.debug("Sending historical data" + Util.toXML(tickData));
    ewadapter.sendHistoricalData(tickData);
  }

  def managedAccounts(accounts: String) {
    logger.debug("managedAccounts" + Util.toXML(accounts));

  }

  def nextValidId(nextValidId: Int) {
    logger.debug("NextValidId" + nextValidId);
  }

  def openOrder(orderId: Int, contract: Contract, order: Order, orderState: OrderState) {
    logger.debug("orderId:" + orderId + "contract" + Util.toXML(contract) + "order" + Util.toXML(order) + "orderState" + Util.toXML(orderState));
  }


  /***
   *
   *
  void orderStatus(int orderId, String status, int filled, int remaining,
double avgFillPrice, int permId, int parentId, double lastFillPrice, int
clientId, String whyHeld)

   */

  def orderStatus(orderId: Int, status: String, filled: Int, remaining: Int, avgFillPrice: Double, permId: Int, parentId: Int, lastFillPrice: Double, clientId: Int, whyHeld: String) {
    this.ewadapter.orderStatus(orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld);
  }

  def realtimeBar(arg0: Int, arg1: Long, arg2: Double, arg3: Double, arg4: Double, arg5: Double, arg6: Long, arg7: Double, arg8: Int) {

  }

  def receiveFA(arg0: Int, arg1: String) {

  }

  def scannerData(arg0: Int, arg1: Int, arg2: ContractDetails, arg3: String, arg4: String, arg5: String, arg6: String) {

  }

  def scannerDataEnd(arg0: Int) {

  }

  def scannerParameters(arg0: String) {

  }

  def tickEFP(arg0: Int, arg1: Int, arg2: Double, arg3: String, arg4: Double, arg5: Int, arg6: String, arg7: Double, arg8: Double) {
  }

  def tickGeneric(arg0: Int, arg1: Int, arg2: Double) {

  }

  def tickOptionComputation(arg0: Int, arg1: Int, arg2: Double, arg3: Double, arg4: Double, arg5: Double) {
  }

  /**
  • 1 = bid
  • 2  =  ask
  • 4  =  last
  • 6  =  high
  • 7  =  low
  • 9  =  close
   **/

  def tickPrice(tickerId: Int, field: Int, price: Double, canAutoExecute: Int) {
    this.ewadapter.tickPrice(tickerId, field, price, canAutoExecute);

  }

  def tickSize(arg0: Int, arg1: Int, arg2: Int) {

  }

  //void tickString(int tickerId, int tickType, String value)
  def tickString(tickerId: Int, tickType: Int, value: String) {
    this.ewadapter.tickString(tickerId, tickType, value);
  }

  def updateAccountTime(time: String) {
    this.ewadapter.updateAccountTime(time);

  }

  def updateAccountValue(key: String, value: String, currency: String, accountName: String) {
    this.ewadapter.updateAccountValue(key, value, currency, accountName);
  }

  def updateMktDepth(arg0: Int, arg1: Int, arg2: Int, arg3: Int, arg4: Double, arg5: Int) {

  }

  def updateMktDepthL2(arg0: Int, arg1: Int, arg2: String, arg3: Int, arg4: Int, arg5: Double, arg6: Int) {

  }

  def updateNewsBulletin(arg0: Int, arg1: Int, arg2: String, arg3: String) {

  }

  def updatePortfolio(contract: Contract, position: Int, marketPrice: Double, marketValue: Double, avgCost: Double, unrealizedPNL: Double, realizedPNL: Double, accountName: String) {
    this.ewadapter.updatePortifolio(contract, position, marketPrice, marketValue, avgCost, unrealizedPNL, realizedPNL, accountName);
  }

  def connectionClosed() {
    this.ewadapter.connectionClosed();
  }

  def error(ex: Exception) {
    this.ewadapter.error(ex.getMessage());
  }

  def error(error: String) {
    this.ewadapter.error(error);
  }

  def error(tickerIdOrOrderId: Int, errorCode: Int, error: String) {
    this.ewadapter.error(tickerIdOrOrderId, errorCode, error);
  }
}
